package com.samp.solr.hanlp.utils;


import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.Segment;
import com.hankcs.hanlp.seg.common.Term;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;

public class SpeakExtract {

    public static final String TOKENIZE_TYPE_HMM = "hmm";

    private static Set<String> speakActionSet = new HashSet<>();

    static {
        speakActionSet.add("说");
        speakActionSet.add("表示");
        speakActionSet.add("告诉");
        speakActionSet.add("谈话");
        speakActionSet.add("介绍");
    }


    public static String rawDoc = "人民网西雅图10月30日电（记者 邓圩）“美丽的西雅图，在中美经贸发展史上，有着浓墨重彩的一笔。”10月29日，在与华盛顿州工商界的见面会上，中国驻旧金山总领事王东华说。40年前，一艘悬挂着中华人民共和国国旗的货轮抵达华盛顿州西雅图港，开启了中美贸易合作的历史篇章，结束了中美两国几十年不通航的历史。 10月29日到31日，中国驻旧金山总领事王东华以及北加州中资企业来到华盛顿州首府西雅图，中美政商企业聚集一堂，友好、合作、交流成为共同的主题。 “两国合作给企业和人民带来了实实在在的利益” 10月29日，王东华总领事一行与华盛顿州政商界以及华盛顿州中国总商会企业近两百人见面。包括华盛顿州副州长Cyrus Habib,西雅图副市长Mike Fong、前美国驻中国大使骆家辉等当地企业、政府和机构人士参加会见交流。 “中国是华盛顿州最大的贸易伙伴！”华盛顿州副州长Cyrus Habib热情欢迎了王东华总领事一行，他对中美企业在华盛顿州展开合作充满期待，“华盛顿州在税费和电价等营商环境方面有着比加州更加优惠的条件，全州拥有生物科技、新能源、电子、海洋工程等7大门类主要产业，一直与中国有着长久的合作历史，有很好合作基础。” 中国是华盛顿州最大的出口目的地，不仅仅是波音飞机、微软等高科技产品、制造业商品，来自华盛顿州的樱桃、苹果、小麦等农产品也随着一艘艘商船抵达中国。华盛顿州工商界人士向来访的王东华总领事和北加州中资企业代表团介绍。 “中美两国已经形成了‘你中有我，我中有你’的深度交融格局。”中国驻旧金山总领事王东华表示，2017年，美国对华货物出口1298.9亿美元，比2011年增长577%，远远高于美国对全球112%的增长，对促进美国经济增长、消费者福利以及经济结构是发挥了重要作用。并为美国带来大量的就业机会，单是2015年美国对华出口和中美双向投资就支持了260万个就业岗位。遍布美国46个州的中国对美投资，为美国国内直接创造就业岗位超过14万个。 王东华说，两国合作的丰硕成果给两国企业和两国人民带来了实实在在的利益。 会谈的气氛轻松而友好，与会企业纷纷交流各自在中美贸易中的收获和故事。 “去年‘双11’当天，本地的一个家庭作坊卖出了150万美元的咸杏仁！”来自塔库玛郡（Tacoma）世贸中心资深贸易顾问迈克·佛雷(Mike Fowler)告诉大家。 大家谈起西雅图企业星巴克每15个小时在中国开一个分店的奇迹，谈起本土创新科技企业与中国企业的积极合作，他们对阿里巴巴、华为、腾讯等中国企业如数家珍。贝尔维尤（Bellevue）市市长John Chelminiak特别提到，听说华为要在美国建立消费者总部，十分欢迎华为把这个部门设在华盛顿州。 斯卡吉特郡经济发展联盟（Skagit County）CEO 约翰·斯特林奇向王东华总领事和中国企业推介自己的地区，斯卡吉特地处温哥华与西雅图之间，营商环境好，他希望中国企业能来看一看，寻找共同发展机会。 王东华总领事表示，合作是双方唯一正确选择，呼吁尽早结束贸易冲突，避免对两国人民带来进一步伤害、对两国长远合作造成不利影响。 “贸易战不是解决问题的正确方法 ” 在交流会上，前美国驻中国大使骆家辉对目前中美贸易关系发表看法说：“尽管自尼克松总统访华以来，美国与中国的关系逐年进步，贸易稳步增长。但令人遗憾的是，我们今天处于中美关系受到严峻考验的气氛中。华盛顿州的许多公司和政策制定者都对贸易投资深感担忧。” “我们不支持这场贸易战，并希望你们能记住华盛顿州，记住微软、波音以及我们的农产品企业这些优秀的公司，请记住你们的朋友。”华盛顿州政商界人士回顾了中国几代领导人到访西雅图的情形，纷纷表示，华盛顿州非常支持加强与中国的经济联系。 “所有人都会同意贸易战不是解决问题的正确方法，只有通过相互协商，讨论和协作才能达到目的。因为在贸易战中，没有赢家，只有失败者。”骆家辉的谈话引起与会者共鸣。 王东华总领事重点与当地工商政界人士谈到了当前中美经贸关系中的几个主要问题。 一是中国在保护知识产权方面的态度是坚定的，重组了国家知识产权局，修订了相关法律法规，下一步还要对《著作权法》、《专利法》进行进一步修改；在北京、上海和广州设立了三个知识产权法庭，15个城市建立了跨省市的知识产权专门审判机构；而中国对全世界支付的知识产权使用费也从2001年的19亿美元上升到2017年单纯对美国支付知识产权使用费就达到71.3亿美元。二是中国政府从来没有强制要求跨国公司转移技术给中国企业，即使有技术转移情况，也是合资企业之间正常、平等的商业契约行为；外国企业在绝大多数领域都可以建立独资企业，建立独资企业更不存在技术转让问题。三是贸易逆差问题。美国是不是“吃了亏”？从1979年1992年，中国一直是逆差，直到1993年才开始呈现顺差，这个与两国发展阶段和创业竞争力变化密切相关；事实上美国在资本技术密集型产品、农产品及服务业方面都是巨大顺差";


    public static List<Term> getTermList(String tokenizeType){
        List<Term> termList = null;
        if( TOKENIZE_TYPE_HMM.equals(tokenizeType) ) {
            Segment segment = HanLP.newSegment().enableAllNamedEntityRecognize(true);
            termList = segment.seg(rawDoc);
        }
        System.out.println(termList);
        return termList;
    }

    /**
     * 判断是否是讲话的起点，判断标准：
     * 以“开头,并且上一Term必须是标点符号。
     * @param
     * @return
     */
    private static boolean isBeginSpeakTerm(Term parentTerm, Term term){
        if( "“".equals(term.word) && (parentTerm == null || "w".equals(parentTerm.nature.toString()))){
            return true;
        }
        return false;
    }

    /**
     * 判断是否是讲话的终点，判断标准：
     * 以”开头。
     * @param
     * @return
     */
    private static boolean isEndSpeakTerm(Term term){
        if( "”".equals(term.word) ){
            return true;
        }
        return false;
    }

    public static boolean isSpeakActionWord(Term term){
        return speakActionSet.contains(term.word);
    }

    /**
     * 找到双引号前是否有说话的人，倒着找。判断标准：
     * 1：有讲话的动作。
     * 2：有讲话的人。
     * 3：前面不能有句号。
     * @param termList
     * @param i
     * @return
     */
    public static String getSpeakPersonPervious(List<Term> termList, int i){
        if( i <= 0 ){
            return null;
        }
        Set<String> nameSet = new HashSet<>();
        nameSet.add("nrf");
        nameSet.add("nr");
        String sepakMan = null;
        boolean hasSpeakAction = false;
        for( ; i > 0 ; i-- ){
            Term term = termList.get(i);
            if( isSpeakActionWord(term) ){
                hasSpeakAction = true;
            }
            //如果是标点符号，但不是冒号，退出。
            if( "w".equals(term.nature.toString()) ){
                if( !("：".equals(term.word) || ":".equals(term.word)) ){
                    break;
                }
            }
            if( nameSet.contains(term.nature.toString()) ){
                sepakMan = term.word;
            }
            if( hasSpeakAction && sepakMan != null ){
                break;
            }
        }
        return sepakMan;
    }

    private static String getLastPersonName(List<Term> termList, int i){
        if( i <= 0 ){
            return null;
        }
        Set<String> nameSet = new HashSet<>();
        nameSet.add("nrf");
        nameSet.add("nr");
        int maxloop = 20;//最多向前循环20个
        for( ; i > 0 ; i-- ){
            if( maxloop < 0 ){
                return null;
            }
            Term term = termList.get(i);
            if( nameSet.contains(term.nature.toString()) ){
                return term.word;
            }
            maxloop--;
        }
        return null;
    }



    /**
     * 当前说话动作，是否是对之前说话人的提及，判断标准：
     * 1：说话动作后，跟着结束标点符号
     * @param termList
     * @param i
     * @return
     */
    private static boolean isEndSpeakActoin(List<Term> termList, int i){
        Set<String> endWSet = new HashSet<>();
        endWSet.add("。");
        endWSet.add("！");
        endWSet.add("，");
        int maxLoop = i+5;
        for( ; i < maxLoop ; i++ ){
            Term term = termList.get(i);
            if( "w".equals(term.nature.toString()) && endWSet.contains(term.word)){
                return true;
            }
        }
        return false;
    }

    /**
     * 抽取规则：当发现有前双引号时，判断是否有前speakMan,有，则当前语句归它。没有，保存至stack.
     * 当发现后双引号时，是否已有speakMan,有，归它，没有，保存至stack，并找后续speakMan，找到了stack所有语句归它。
     *
     */
    private static void speakExtract(){
        List<Term> termList = getTermList(TOKENIZE_TYPE_HMM);
        StringBuilder sb = new StringBuilder();
        Stack<String> speakStack = new Stack<>();
        boolean speakStart = false;
        String speakMan = null;
        for(int i = 0 ; i < termList.size() ; i++){
            Term term = termList.get(i);
            Term parentTerm = null;
            if( i > 1 ){
                parentTerm = termList.get(i-1);
            }
            if( isBeginSpeakTerm(parentTerm, term) ){
                speakStart = true;
                speakMan = getSpeakPersonPervious(termList, i-1);
            }
            if( speakStart && isEndSpeakTerm(term) ){
                sb.append(term.word);
                speakStack.push(sb.toString());
                sb.setLength(0);
                speakStart = false;
                if( speakMan != null ){
                    printSpeakWithMan(speakMan, speakStack);
                    speakMan = null;
                }
            }
            if( speakStart ){
                sb.append(term.word);
            }
            if( isSpeakActionWord(term) ){
                if( isEndSpeakActoin(termList, i+1) ){
                    speakMan = getLastPersonName(termList, i-1);
                    printSpeakWithMan(speakMan, speakStack);
                }

            }
        }
        System.out.println("---------------null speak--------------");
        while ( !speakStack.empty() ){
            String speak = speakStack.pop();
            System.out.println(speak);
        }
    }

    private static void printSpeakWithMan(String speakMan, Stack<String> speakStack){
        if( speakMan == null ){
            speakMan = "no found";
        }
        if( speakMan != null && !speakStack.empty()){
            System.out.println("======"+speakMan+"====start======");
            while ( !speakStack.empty() ){
                String speak = speakStack.pop();
                System.out.println(speak);
            }
            System.out.println("======"+speakMan+"=====end=======");
        }
    }

    public static void main(String[] args) {
        try {
//            rawDoc = "在交流会上，前美国驻中国大使骆家辉对目前中美贸易关系发表看法说：“尽管自尼克松总统访华以来，美国与中国的关系逐年进步，贸易稳步增长。但令人遗憾的是，我们今天处于中美关系受到严峻考验的气氛中。华盛顿州的许多公司和政策制定者都对贸易投资深感担忧。” “我们不支持这场贸易战，并希望你们能记住华盛顿州，记住微软、波音以及我们的农产品企业这些优秀的公司，请记住你们的朋友。”华盛顿州政商界人士回顾了中国几代领导人到访西雅图的情形，纷纷表示，华盛顿州非常支持加强与中国的经济联系。 “所有人都会同意贸易战不是解决问题的正确方法，只有通过相互协商，讨论和协作才能达到目的。因为在贸易战中，没有赢家，只有失败者。”骆家辉的谈话引起与会者共鸣。";
            speakExtract();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
